<!DOCTYPE html>
<html>
<!-- 
热像素检测工具 - 主界面
功能：用于检测和修正FITS图像中的热像素
主要模块：
1. 导航栏 - 提供首页、检测结果和历史记录链接
2. 方法选择 - 提供全局统计和局部统计两种检测方法
3. 参数设置 - 根据选择的方法显示不同的参数选项
4. 文件上传 - 支持多FITS文件上传
5. 处理结果 - 显示检测结果和修正后的图像
-->
<head>
    <title>热像素检测工具</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <!-- 加载主样式文件 -->
    <link rel="stylesheet" href="/static/css/main.css?v=2">    
    <style>        
        h1 {
            color: var(--primary-color);
            margin-bottom: 30px;
            text-align: center;
        }
        
        select, input[type="number"] {
            width: 100px;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 16px;
            background-color: white;
        }
        
        input[type="number"]:focus {
            border-color: #4CAF50;
            box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.1);
        }
        
        /* 基础文件输入样式 */
        input[type="file"] {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background-color: white;
        }
        
        button {
            padding: 12px 24px;
            background-color: var(--primary-color);
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: var(--hover-color);
        }

        .result {
            margin-top: 30px;
            padding: 20px;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        .section-title, .result h3 {
            color: var(--primary-color);
            margin: 5px 0 15px 0;  
            border-bottom: 1px solid #eee;
            padding: 5px 0 10px 0;  
            font-size: 1.5rem;
            font-weight: 600;
        }
        .result-section {
            margin-bottom: 30px;
            padding-bottom: 15px;
            border-bottom: 1px dashed #eee;
        }
        .result-controls {
            margin-bottom: 20px;
        }
        .result-images {
            display: flex;
            gap: 20px;
            flex-wrap: wrap;
            margin-top: 15px;
        }
        .result-image {
            flex: 1;
            min-width: 300px;
        }
        #result-selector {
            padding: 10px;
            border-radius: 4px;
            border: 1px solid #ddd;
            font-size: 16px;
            width: 100%;
            max-width: 500px;
        }
        .result-image h5 {
            margin-bottom: 10px;
            color: #555;
        }
        .result-image img {
            max-width: 100%;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        .result-link {
            display: inline-block;
            margin-top: 15px;
            padding: 8px 15px;
            background-color: var(--primary-color);
            color: white;
            border-radius: 4px;
            text-decoration: none;
            transition: background-color 0.3s;
        }
        .result-link:hover {
            background-color: var(--hover-color);
        }
    </style>
</head>
<body class="page-transition">
  <!-- 顶部导航栏 -->
  <div class="nav-links">
    <a href="/" class="nav-link active"><i class="fas fa-home"></i> 首页</a>
    <a href="/results" class="nav-link"><i class="fas fa-list"></i> 检测结果</a>
    <a href="/history" class="nav-link"><i class="fas fa-history"></i> 历史记录</a>
    <a href="/stats" class="nav-link"><i class="fas fa-chart-bar"></i> 结果统计</a>
  </div>

  <!-- 页面主内容容器 -->
  <div class="container">
    <h1><i class="fas fa-camera"></i> 热像素检测工具</h1>

    <div style="margin-bottom: 30px; background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1);">
      <h3 class="section-title"><i class="fas fa-cogs"></i> 检测方法</h3>
      <div class="form-group" style="display: flex; align-items: center; gap: 15px; margin-top: 15px;">
        <label for="method" style="white-space: nowrap;">方法选择:</label>
        <select id="method" name="method" style="font-size: 18px; padding: 10px; height: 50px; width: 25%; min-width: 200px;">
          <option value="v1" style="font-size: 16px;">全局统计方法</option>
          <option value="v2" style="font-size: 16px;">局部统计方法</option>
          <option value="v3" style="font-size: 16px;">锐度统计方法</option>
        </select>
      </div>
    </div>

    <div id="parameters-container" style="background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); margin-bottom: 20px;"></div>

    <div style="margin-bottom: 20px; background-color: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 6px rgba(0,0,0,0.1);">
      <h3 class="section-title"><i class="fas fa-file-upload"></i> 图像输入</h3>
      <div class="form-group" style="margin-top: 15px;">
        <label for="file" style="min-width: 120px;">选择FITS文件:</label>
        <input type="file" id="file" name="files" accept=".fits,.fit" multiple 
              style="flex-grow: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px;"/>
      </div>
    </div>

    <button id="detect-btn" style="padding: 10px 20px; font-size: 24px; border-radius: 4px; cursor: pointer; transition: background-color 0.3s;"><i class="fas fa-search"></i> 开始处理</button>

    <div id="loading" class="progress-container" style="display: none;">
      <!-- 顶部状态栏 -->
      <div class="progress-header">
        <div class="progress-left">
          <div class="spinner"></div>
          <span id="progress-text">
            正在处理：<span id="current-file">---</span>
          </span>
        </div>
        <div class="progress-right">
          <strong>进度:</strong> <span id="progress-percent">0%</span>
        </div>
      </div>
      <!-- 进度条 -->
      <progress id="progress" value="0" max="100" class="progress-bar"></progress>
      <!-- 可选额外进度描述 -->
      <div id="file-progress"></div>
    </div>

    <div id="result" class="result" style="display: none;">
      <h3><i class="fas fa-chart-bar"></i> 检测结果</h3>
      <div id="images"></div>
      <p><a href="/results" class="result-link"><i class="fas fa-list"></i> 查看详情</a></p>
    </div>
  </div>

  <script>
    function renderParams(method) {
      const container = document.getElementById('parameters-container');
      container.innerHTML = '<h3 class="section-title"><i class="fas fa-sliders-h"></i> 检测参数</h3><div class="params-grid">';

      if(method === 'v1') {
        container.innerHTML += `
          <div style="display: flex; flex-wrap: wrap; gap: 15px;">
            <div class="form-group">
              <label for="sigma_threshold"><i class="fas fa-sigma"></i> Sigma阈值</label>
              <input type="number" id="sigma_threshold" name="sigma_threshold" value="5" step="0.1" />
            </div>
            <div class="form-group">
              <label for="median_size"><i class="fas fa-filter"></i> 中值滤波大小</label>
              <input type="number" id="median_size" name="median_size" value="3" />
            </div>
          </div>`;
      } else if(method === 'v2') {
        container.innerHTML += `
          <div style="display: flex; flex-wrap: wrap; gap: 15px;">
            <div class="form-group">
              <label for="sigma_threshold"><i class="fas fa-sigma"></i> Sigma阈值</label>
              <input type="number" id="sigma_threshold" name="sigma_threshold" value="5" step="0.1" />
            </div>
            <div class="form-group">
              <label for="median_size"><i class="fas fa-filter"></i> 中值滤波大小</label>
              <input type="number" id="median_size" name="median_size" value="3" />
            </div>
            <div class="form-group">
              <label for="local_window"><i class="fas fa-expand"></i> 局部窗口大小</label>
              <input type="number" id="local_window" name="local_window" value="21" />
            </div>
            <div class="form-group">
              <label for="min_value"><i class="fas fa-arrow-down"></i> 最小像素值</label>
              <input type="number" id="min_value" name="min_value" value="1000" />
            </div>
            <div class="form-group">
              <label for="max_cluster_size"><i class="fas fa-arrows-alt"></i> 最大簇大小</label>
              <input type="number" id="max_cluster_size" name="max_cluster_size" value="3" />
            </div>
          </div>`;
      } else if (method === 'v3') {
        container.innerHTML += `
          <div style="display: flex; flex-wrap: wrap; gap: 15px;">
            <div class="form-group">
              <label for="n_threshold"><i class="fas fa-chart-line"></i> 波动阈值</label>
              <input type="number" id="n_threshold" name="n_threshold" value="5" step="0.5" min="1" max="20" />
            </div>
            <div class="form-group">
              <label for="concentration_ratio"><i class="fas fa-percent"></i> 亮度锐度</label>
              <input type="number" id="concentration_ratio" name="concentration_ratio" value="0.5" step="0.05" min="0.1" max="1" />
            </div>
            <div class="form-group">
              <label for="use_absolute_diff"><i class="fas fa-exchange-alt"></i> 校验暗像素</label>
              <select id="use_absolute_diff" name="use_absolute_diff">
                <option value="true" selected>是</option>
                <option value="false">否</option>
              </select>
            </div>
          </div>
        `;
      }
      container.innerHTML += '</div>';
    }

    document.addEventListener('DOMContentLoaded', () => {
      const methodSelect = document.getElementById('method');
      renderParams(methodSelect.value);

      methodSelect.addEventListener('change', e => {
        renderParams(e.target.value);
      });

      document.getElementById('detect-btn').addEventListener('click', async () => {
        const files = document.getElementById('file').files;
        if (!files.length) {
          alert('请选择FITS文件');
          return;
        }

        const formData = new FormData();
        const method = methodSelect.value;
        formData.append('method', method);

        for (const f of files) {
          formData.append('files', f);
        }

        let params = [];
        if (method === 'v1') {
          params = ['sigma_threshold', 'median_size'];
        } else if (method === 'v2') {
          params = ['sigma_threshold', 'median_size', 'local_window', 'min_value', 'max_cluster_size'];
        } else if (method === 'v3') {
          params = ['n_threshold', 'concentration_ratio', 'use_absolute_diff'];
        }

        params.forEach(p => {
          const el = document.getElementById(p);
          if (el && el.value !== '') {
            let val = el.value;
            if (p === 'use_absolute_diff') {
              // 显式将字符串转为 "true" / "false"
              val = (val === 'true').toString();
            }
            formData.append(p, val);
          }
        });

        try {
          // 显示加载状态
          document.getElementById('loading').style.display = 'block';
          document.getElementById('detect-btn').disabled = true;
          document.getElementById('result').style.display = 'none';
          document.getElementById('images').innerHTML = '';
          document.getElementById('progress').value = 0;

          // 第一步：上传文件并获取 task_id
          const res = await fetch('/api/process', { method: 'POST', body: formData });
          const data = await res.json();

          if (!data.success) {
            alert('检测失败: ' + (data.error || '未知错误'));
            return;
          }

          const taskId = data.task_id;

          // 第二步：启动任务
          const startRes = await fetch(`/api/process/start/${taskId}`, { method: 'POST' });
          const startData = await startRes.json();

          if (!startData.success) {
            alert('启动任务失败: ' + (startData.error || '未知错误'));
            return;
          }

          // 第三步：轮询进度（加入延迟重试、最多尝试次数）
          let retryCount = 0;
          const maxRetry = 10;

          const checkProgress = async () => {
            try {
              const resp = await fetch(`/api/progress/${taskId}`);
              if (!resp.ok) {
                console.warn('进度接口状态异常:', resp.status);
                if (resp.status === 404 && retryCount < maxRetry) {
                  retryCount++;
                  setTimeout(checkProgress, 1500);
                } else {
                  alert('查询进度失败，服务异常');
                }
                return;
              }

              const progData = await resp.json();
              if (progData.success) {
                document.getElementById('progress').value = progData.progress;
                document.getElementById('progress-percent').textContent = progData.progress + '%';
                document.getElementById('current-file').textContent = progData.current_file;

                if (progData.status === 'done') {
                  // 加载完成，隐藏 loading 和恢复按钮（✅ 修复点）
                  document.getElementById('loading').style.display = 'none';
                  document.getElementById('detect-btn').disabled = false;

                  const resultRes = await fetch(`/api/result/${taskId}`);
                  if (!resultRes.ok) {
                    alert('获取结果失败，状态码：' + resultRes.status);
                    return;
                  }

                  const resultData = await resultRes.json();
                  if (resultData.success) {
                    const imagesDiv = document.getElementById('images');
                    imagesDiv.innerHTML = `
                      <div class="result-controls">
                        <select id="result-selector">
                          ${resultData.results.map((item, index) =>
                            `<option value="${index}">${item.filename}</option>`
                          ).join('')}
                        </select>
                        <div id="selected-result"></div>
                      </div>
                    `;

                    const resultSelector = document.getElementById('result-selector');
                    const selectedResult = document.getElementById('selected-result');

                    function showSelectedResult(index) {
                      const item = resultData.results[index];
                      selectedResult.innerHTML = `
                        <div class="result-images">
                          <div class="result-image">
                            <h5>原始图像</h5>
                            <img src="data:image/png;base64,${item.original_image}" alt="原始图像" />
                          </div>
                          <div class="result-image">
                            <h5>热像素图像</h5>
                            <img src="data:image/png;base64,${item.hot_pixel_image}" alt="热像素图" />
                          </div>
                          <div class="result-image">
                            <h5>修正后图像</h5>
                            <img src="data:image/png;base64,${item.corrected_image}" alt="修正后图像" />
                          </div>
                        </div>
                        <div style="margin-top: 12px;">
                          <strong>识别热像素点数:</strong> ${item.hot_pixel_count || 'N/A'}
                        </div>
                      `;
                    }

                    resultSelector.addEventListener('change', (e) => {
                      showSelectedResult(e.target.value);
                    });

                    showSelectedResult(0);
                    document.getElementById('result').style.display = 'block';
                  } else {
                    alert('获取结果失败: ' + (resultData.error || '未知错误'));
                  }
                } else {
                  setTimeout(checkProgress, 1000);
                }
              } else {
                alert('进度接口失败: ' + (progData.error || '未知错误'));
              }
            } catch (e) {
              console.error('轮询进度接口出错:', e);
              setTimeout(checkProgress, 2000);
            }
          };

          // 延迟 1 秒开始轮询，避免后端 task 尚未初始化
          setTimeout(checkProgress, 1000);

        } catch (e) {
          alert('请求失败: ' + e.message);
          console.error(e);
          document.getElementById('loading').style.display = 'none';
          document.getElementById('detect-btn').disabled = false;
        }
      });
    });

  </script>

</body>

</html>